package com.swak.consistency.tcc.role.impls;

import com.swak.consistency.tcc.context.TccContext;
import com.swak.consistency.tcc.role.AbstractTransRoler;
import com.swak.consistency.tcc.role.Role;

/**
 * 事务完成者；
 * 
 * 1. 先执行第一阶段事务
 * 2. 发起第二阶段事务的执行
 * 
 * @author DELL
 */
public class TransCompleter extends AbstractTransRoler {

	@Override
	public Object doHandle(TccContext context) {

		/*
		 * 执行的角色
		 */
		Role role = context.getRole();

		// 执行结果
		Object result = null;
		Throwable error = null;

		try {
			// 执行准备阶段
			result = context.getProceeding().proceed();
		} catch (Throwable e) {
			error = e;
		}

		// 发起者才需要执行后续
		if (role == Role.INITIATOR) {
			// 执行期间异常
			if (error != null) {
				this.quietExecute(() -> {
					this.doCancel(context);
				});
				return this.throwConsistencyException(error);
			}

			// 确认提交
			this.quietExecute(() -> {
				this.doConfirm(context);
			});
		}

		// 其他角色如有异常则直接抛出
		else if (error != null) {
			return this.throwConsistencyException(error);
		}

		// 返回结果
		return result;
	}

	// 不抛出异常
	private void quietExecute(Runnable run) {
		try {
			run.run();
		} catch (Throwable e) {
			// ig
		}
	}
}